package com.bibrApp.difu.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;


import com.bibrApp.difu.R;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.appcompat.widget.AppCompatImageView;


/** 圆角矩形
 * Created by dj on 2020/3/21
 */
public class RoundImageView extends AppCompatImageView {

  private MaskType mMaskType;
  private Path mPath;
  private float mRadius;
  private float mBorderWidth;
  private Paint mBorderPaint;
  private int mBorderColor;
  private static final int DEFAULT_BORDER_COLOR = Color.WHITE;

  private static final MaskType[] MASK_TYPES = {
    MaskType.RECTANGLE, MaskType.CIRCLE, MaskType.ROUNDRECTANGLE, MaskType.ROUNDRECTANGLETOP, MaskType.ROUNDRECTANGLETOP
  };

  public RoundImageView(Context context) {
    super(context);
    initRoundImageView();
  }

  public RoundImageView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    initRoundImageView();
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.sol_RoundImageView, defStyle, 0);
    int index = a.getInt(R.styleable.sol_RoundImageView_sol_maskType, -1);
    if (index >= 0) {
      setMaskType(MASK_TYPES[index]);
    }
    mRadius = a.getDimensionPixelSize(R.styleable.sol_RoundImageView_sol_roundRadius, 10);
    mBorderColor = a.getColor(R.styleable.sol_RoundImageView_sol_borderColor_Ri, Color.BLACK);
    mBorderWidth = a.getDimensionPixelSize(R.styleable.sol_RoundImageView_sol_borderWidth_Ri, 0);

    a.recycle();
  }

  private void initRoundImageView() {
    mMaskType = MaskType.CIRCLE;
    mRadius = 10;
    mPath = new Path();
    mBorderPaint = new Paint();
    mBorderColor = DEFAULT_BORDER_COLOR;
    mBorderPaint.setColor(mBorderColor);
  }

  /**
   *
   * @MaskType.ROUNDRECTANGLE
   * @MaskType.ROUNDRECTANGLETOP
   * @param radius
   */
  public void setRadius(int radius) {
    if (mRadius == radius) {
      return;
    }

    mRadius = radius;
    invalidate();
  }

  public void setBorderColor(@ColorInt int color) {
    if (mBorderColor == color) {
      return;
    }

    mBorderColor = color;
    mBorderPaint.setColor(color);
    invalidate();
  }

  public void initAll(float borderWidth, MaskType maskType, int radius, @ColorInt int borderColor) {
    mBorderWidth = borderWidth;
    mMaskType = maskType;
    mRadius = radius;
    mBorderColor = borderColor;
  }

  public void setBorderColorResource(@ColorRes int colorResource) {
    setBorderColor(getContext().getResources().getColor(colorResource));
  }

  public void setBorderWidth(float borderWidth) {
    if (mBorderWidth == borderWidth) {
      return;
    }
    mBorderWidth = borderWidth;
    invalidate();
  }

  public void setMaskType(MaskType maskType) {
    if (maskType != null && !mMaskType.equals(maskType)) {
      mMaskType = maskType;
      requestLayout();
      invalidate();
    }
  }

  @Override
  protected void onDraw(Canvas canvas) {
    canvas.save();
    drawPath();
    canvas.clipPath(mPath);
    super.onDraw(canvas);
    canvas.restore();
    drawCanvas(canvas);
  }

  private void drawPath() {
    int width = getWidth();
    int height = getHeight();
    switch (mMaskType) {
      case RECTANGLE:
        mPath.reset();
        mPath.addRect(
            new RectF(mBorderWidth / 2, mBorderWidth / 2, width - mBorderWidth / 2, height - mBorderWidth / 2),
            Path.Direction.CW);
        mPath.close();
        break;
      case CIRCLE:
        float r = Math.min(width, height) / 2.0f;
        mPath.reset();
        mPath.addCircle(width / 2.0f, height / 2.0f, r, Path.Direction.CW);
        mPath.close();
        break;
      case ROUNDRECTANGLE:
        mPath.reset();
        mPath.addRoundRect(
            new RectF(mBorderWidth / 4, mBorderWidth / 4, width - mBorderWidth / 4, height - mBorderWidth / 4),
            mRadius,
            mRadius,
            Path.Direction.CW);
        mPath.close();
        break;
      case ROUNDRECTANGLETOP:
        mPath.reset();
        mPath.addCircle(mRadius, mRadius, mRadius, Path.Direction.CW);
        mPath.addCircle(width - mRadius, mRadius, mRadius, Path.Direction.CW);
        mPath.addRect(mRadius, 0, width - mRadius, 2 * mRadius, Path.Direction.CW);
        mPath.addRect(0, mRadius, width, height, Path.Direction.CW);
        mPath.close();
        break;
      case ROUNDRECTANGLERIGHTTOP:
        mPath.reset();
        mPath.addCircle(mRadius, mRadius, mRadius, Path.Direction.CW);
        mPath.addCircle(width - mRadius, mRadius, mRadius, Path.Direction.CW);
        mPath.addRect(0, 0, width - mRadius, 2 * mRadius, Path.Direction.CW);
        mPath.addRect(0, mRadius, width, height, Path.Direction.CW);
        mPath.close();
        break;
      default:
        break;
    }
  }

  private void drawCanvas(Canvas canvas) {
    int width = getWidth();
    int height = getHeight();
    if (mBorderWidth <= 0) {
      return;
    }
    mBorderPaint.setColor(mBorderColor);
    mBorderPaint.setStrokeWidth(mBorderWidth);
    mBorderPaint.setStyle(Paint.Style.STROKE);
    mBorderPaint.setAntiAlias(true);
    switch (mMaskType) {
      case RECTANGLE:
        canvas.drawRect(new RectF(0, 0, width, height), mBorderPaint);
        break;
      case CIRCLE:
        float r = Math.min(width, height) / 2.0f;
        canvas.drawCircle(width / 2.0f, height / 2.0f, r - mBorderWidth / 2, mBorderPaint);
        break;
      case ROUNDRECTANGLE:
        canvas.drawRoundRect(new RectF(0, 0, width, height), mRadius, mRadius, mBorderPaint);
        break;
      default:
        break;
    }
  }

  /**
   * options for mask the imageview
   */
  public enum MaskType {

    /**
     * a parallelogram with four right angles
     */
    RECTANGLE(0),
    /**
     *
     */
    CIRCLE(1),
    /**
     *a parallelogram with four circle angles
     */
    ROUNDRECTANGLE(2),

    /**
     * a parallelogram with two top circle angles
     */
    ROUNDRECTANGLETOP(3),

    /**
     * a parallelogram with right top circle angles
     */
    ROUNDRECTANGLERIGHTTOP(4);

    final int mNativeInt;

    MaskType(int ni) {
      mNativeInt = ni;
    }
  }
}
